#include "DesaparecedorFicha.h"
#include "DesplazadorColumna.h"

#include <iostream>
#include <list>

DesaparecedorFicha::DesaparecedorFicha(std::list<Json::Value> *tableros,
                                       VistaEscenario *vista, Mutex *m) {
    this->finAnimacion = finAnimacion;

    this->vista = vista;
    tamanio = 50;

    this->m = m;
    this->tableros = tableros;
    this->desplazador_columna=NULL;
}

void *DesaparecedorFicha::run() {
    Json::Value fichasADesaparecer = tableros->front();
    tableros->pop_front();

    Juego::reproductorWav.reproducir(SON_COMBINACION);

    int x, y;

    for (int i = 0; i < 45; i++) {
        for (unsigned int j = 0; j < fichasADesaparecer.size(); j++) {
            Json::Value ficha = fichasADesaparecer[j];
            x = ficha["x"].asInt();
            y = ficha["y"].asInt();

            m->lock();
            // para que el desvanecimiento se vea centrado
            if (i % 2 == 0) { 
                vista->vistaFichas[x][y]->buffer =
                    vista->vistaFichas[x][y]->obtenerImagen(i);
                vista->vistaFichas[x][y]->xDesde++;
                vista->vistaFichas[x][y]->yDesde++;
            }
            m->unlock();
        }

        usleep(TIEMPO_DE_REFRESCO*1000);
    }

    /* Elimino las fichas que desaparecieron */
    m->lock();
    Json::Value magicasAAparecer;

    for (unsigned int j = 0; j < fichasADesaparecer.size(); j++) {
        Json::Value ficha = fichasADesaparecer[j];
        x = ficha["x"].asInt();
        y = ficha["y"].asInt();
        if (MODO_DEBUG==1){
            std::stringstream ss;
            ss << "Eliminando: " << x << "," << y;
            Log::loguear(MDEBUG, ss.str());
        }   
        if (ficha["magica"].asBool()==true)
            magicasAAparecer.append(ficha);
        delete vista->vistaFichas[x][y];
        vista->vistaFichas[x][y] = NULL;
    }
    m->unlock();

    /* Aparecen las fichas que fueron convertidas (magicas) */
    if (magicasAAparecer.size()>0){
        /**** REFACTOR: codigo repetido de aparecedor *****/
        VistaFichaTablero *vistaFicha = NULL;
        int x, y;
        std::string candyName, colorName;
        for (unsigned int i = 0; i < magicasAAparecer.size(); i++) {
            vistaFicha = NULL;
            x = magicasAAparecer[i]["x"].asInt();
            y = magicasAAparecer[i]["y"].asInt();
            candyName=magicasAAparecer[i]["candy"].asString();
            colorName=magicasAAparecer[i]["color"].asString();
            if (candyName == BUTTON) {
              vistaFicha = new VistaButton(colorName,false, x, y);
            } else if (candyName == MINIBARV) {
              vistaFicha = new VistaMiniBar(colorName,false, x, y, VERTICAL);
            } else if (candyName == MINIBARH) {
              vistaFicha = new VistaMiniBar(colorName,false, x, y, HORIZONTAL);
            } else if (candyName == GOLDENSTAR) {
              vistaFicha = new VistaGoldenStar(colorName,false, x, y);
            } else {
              Log::loguear(MERROR, "Error: candy invalido!");
            }

            m->lock();
            if (vistaFicha!=NULL){
                if (MODO_DEBUG==1){
                    std::stringstream ss;
                    ss << "<PARSER> Aparece (magica): "
                       << "(x,y)= " << x << "," << y
                       << ", Candy: " << candyName
                       << ", Color: " << colorName;
                    Log::loguear(MDEBUG,ss.str());
                }

                vistaFicha->yDesde += 23;
                vistaFicha->xDesde += 23;
            }
            vista->vistaFichas[x][y] = vistaFicha;
            m->unlock();
        }

        /* Las hace aparecer gradualmente */
        for (int i = 45; i >= 0; i--) {
            m->lock();
            for (unsigned int j = 0; j < magicasAAparecer.size(); j++) {
                if (i % 2 == 0) {
                    x = magicasAAparecer[j]["x"].asInt();
                    y = magicasAAparecer[j]["y"].asInt();
                    vista->vistaFichas[x][y]->buffer =
                                    vista->vistaFichas[x][y]->obtenerImagen(i);
                    vista->vistaFichas[x][y]->yDesde -= 1;
                    vista->vistaFichas[x][y]->xDesde -= 1;
                }
            }
            m->unlock();
            usleep(TIEMPO_DE_REFRESCO*1000);
        }

    /******************/
    }


    this->desplazador_columna = new DesplazadorColumna(tableros, vista, m);
    this->desplazador_columna->start();

    this->desplazador_columna->join();
    this->exit();
    return NULL;
}

DesaparecedorFicha::~DesaparecedorFicha() {
    if (this->desplazador_columna!=NULL){
     Log::loguear(MDEBUG,"Liberando desaparecedor de columnas (2/4)...");
     delete this->desplazador_columna;
     this->desplazador_columna=NULL;
    }
}
